Allow admins to login as another user (#1659)

* switch_to_user and switch_back routes

* Uses session to store original user id

Albert Sun 7 years ago
parent
commit
6bb61065ec

+ 23 - 2
app/controllers/admin/users_controller.rb

@@ -1,7 +1,7 @@
1 1
 class Admin::UsersController < ApplicationController
2
-  before_action :authenticate_admin!
2
+  before_action :authenticate_admin!, except: [:switch_back]
3 3
 
4
-  before_action :find_user, only: [:edit, :destroy, :update, :deactivate, :activate]
4
+  before_action :find_user, only: [:edit, :destroy, :update, :deactivate, :activate, :switch_to_user]
5 5
 
6 6
   helper_method :resource
7 7
 
@@ -83,6 +83,27 @@ class Admin::UsersController < ApplicationController
83 83
     end
84 84
   end
85 85
 
86
+  # allow an admin to sign-in as any other user
87
+
88
+  def switch_to_user
89
+    if current_user != @user
90
+      old_user = current_user
91
+      sign_in(:user, @user, { bypass: true })
92
+      session[:original_admin_user_id] = old_user.id
93
+    end
94
+    redirect_to agents_path
95
+  end
96
+
97
+  def switch_back
98
+    if session[:original_admin_user_id].present?
99
+      sign_in(:user, User.find(session[:original_admin_user_id]), { bypass: true })
100
+      session.delete(:original_admin_user_id)
101
+    else
102
+      redirect_to(root_path, alert: 'You must be an admin acting as a different user to do that.') and return
103
+    end
104
+    redirect_to admin_users_path
105
+  end
106
+
86 107
   private
87 108
 
88 109
   def find_user

+ 3 - 0
app/views/admin/users/_form.html.erb

@@ -22,5 +22,8 @@
22 22
 <div class="row">
23 23
   <div class="col-md-12">
24 24
     <%= link_to icon_tag('glyphicon-chevron-left') + ' Back'.html_safe, admin_users_path, class: "btn btn-default" %>
25
+    <% if @user.persisted? %>
26
+      <%= link_to 'Become User', switch_to_user_admin_user_path(@user), class: "btn btn-default btn-info", data: { confirm: 'This will log you in as another user. Would you like to continue?' } %>
27
+    <% end %>
25 28
   </div>
26 29
 </div>

+ 3 - 2
app/views/admin/users/index.html.erb

@@ -24,12 +24,13 @@
24 24
               <td><%= link_to user.username, edit_admin_user_path(user) %></td>
25 25
               <td><%= user.email %></td>
26 26
               <td><%= user_account_state(user) %></td>
27
-              <td><%= user.agents.active.count %></td>
28
-              <td><%= user.agents.inactive.count %></td>
27
+              <td><%= link_to user.agents.active.count, switch_to_user_admin_user_path(user), data: { confirm: 'This will log you in as another user. Would you like to continue?' } %></td>
28
+              <td><%= link_to user.agents.inactive.count, switch_to_user_admin_user_path(user), data: { confirm: 'This will log you in as another user. Would you like to continue?' } %></td>
29 29
               <td title='<%= user.created_at %>'><%= time_ago_in_words user.created_at %> ago</td>
30 30
               <td>
31 31
                 <div class="btn-group btn-group-xs">
32 32
                   <% if user != current_user %>
33
+                    <%= link_to 'Become User', switch_to_user_admin_user_path(user), class: "btn btn-default", data: { confirm: 'This will log you in as another user. Would you like to continue?' } %>
33 34
                     <% if user.active? %>
34 35
                       <%= link_to 'Deactivate', deactivate_admin_user_path(user), method: :put, class: "btn btn-default" %>
35 36
                     <% else %>

+ 1 - 1
app/views/agents/index.html.erb

@@ -2,7 +2,7 @@
2 2
   <div class='row'>
3 3
     <div class='col-md-12'>
4 4
       <div class="page-header">
5
-        <h2>Your Agents</h2>
5
+        <h2><%= session[:original_admin_user_id].present? ? "#{current_user.username}’s Agents" : 'Your Agents' %></h2>
6 6
       </div>
7 7
 
8 8
       <%= render 'agents/table' %>

+ 8 - 0
app/views/layouts/_navigation.html.erb

@@ -60,9 +60,17 @@
60 60
     <li class="dropdown">
61 61
       <a href="#" class="dropdown-toggle" data-toggle="dropdown">
62 62
         Account
63
+        <% if user_signed_in? && session[:original_admin_user_id].present? %>
64
+          <span class="label label-warning"><%= current_user.username %></span>
65
+        <% end %>
63 66
         <b class="caret"></b>
64 67
       </a>
65 68
       <ul class="dropdown-menu" role="menu" aria-labelledby="dLabel">
69
+        <% if user_signed_in? && session[:original_admin_user_id].present? %>
70
+          <li>
71
+            <%= link_to 'Switch Back to Admin User', switch_back_admin_users_path, tabindex: '-1' %>
72
+          </li>
73
+        <% end %>
66 74
         <li>
67 75
           <% if user_signed_in? %>
68 76
             <%= link_to 'Account', edit_user_registration_path, :tabindex => "-1" %>

+ 4 - 0
config/routes.rb

@@ -84,6 +84,10 @@ Huginn::Application.routes.draw do
84 84
       member do
85 85
         put :deactivate
86 86
         put :activate
87
+        get :switch_to_user
88
+      end
89
+      collection do
90
+        get :switch_back
87 91
       end
88 92
     end
89 93
   end

+ 37 - 0
spec/controllers/admin/users_controller_spec.rb

@@ -19,4 +19,41 @@ describe Admin::UsersController do
19 19
       end
20 20
     end
21 21
   end
22
+
23
+  describe 'GET #switch_to_user' do
24
+    it "switches to another user" do
25
+      sign_in users(:jane)
26
+
27
+      get :switch_to_user, :id => users(:bob).id
28
+      expect(response).to redirect_to(agents_path)
29
+      expect(subject.session[:original_admin_user_id]).to eq(users(:jane).id)
30
+    end
31
+
32
+    it "does not switch if not admin" do
33
+      sign_in users(:bob)
34
+
35
+      get :switch_to_user, :id => users(:jane).id
36
+      expect(response).to redirect_to(root_path)
37
+    end
38
+  end
39
+
40
+  describe 'GET #switch_back' do
41
+    it "switches to another user and back" do
42
+      sign_in users(:jane)
43
+
44
+      get :switch_to_user, :id => users(:bob).id
45
+      expect(response).to redirect_to(agents_path)
46
+      expect(subject.session[:original_admin_user_id]).to eq(users(:jane).id)
47
+
48
+      get :switch_back
49
+      expect(response).to redirect_to(admin_users_path)
50
+      expect(subject.session[:original_admin_user_id]).to be_nil
51
+    end
52
+
53
+    it "does not switch_back without having switched" do
54
+      sign_in users(:bob)
55
+      get :switch_back
56
+      expect(response).to redirect_to(root_path)
57
+    end
58
+  end
22 59
 end